import {
  Injectable,
  UnauthorizedException,
  ConflictException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserPO } from './users.entity';
import * as bcrypt from 'bcryptjs';
import { JwtService } from '@nestjs/jwt';
import { UserVO } from './vo/user.vo';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(UserPO)
    private usersRepository: Repository<UserPO>,
    private jwtService: JwtService,
  ) {}

  // 注册
  async register(data: any) {
    const { username, password, nickname } = data;
    const exist = await this.usersRepository.findOne({ where: { username } });
    if (exist) throw new ConflictException('用户名已存在');
    const hash = await bcrypt.hash(password, 10);
    const user = this.usersRepository.create({
      username,
      password: hash,
      nickname,
    });
    const userPO = await this.usersRepository.save(user);
    return new UserVO(userPO);
  }

  // 登录
  async login(data: any) {
    const { username, password } = data;
    const user = await this.usersRepository.findOne({ where: { username } });
    if (!user) throw new UnauthorizedException('用户名或密码错误');
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) throw new UnauthorizedException('用户名或密码错误');
    const payload = { id: user.id, username: user.username };
    return {
      token: this.jwtService.sign(payload),
      user: new UserVO(user),
    };
  }

  // 获取用户信息
  async getProfile(userId: number) {
    const user = await this.usersRepository.findOne({ where: { id: userId } });
    if (!user) throw new UnauthorizedException('用户不存在');
    return new UserVO(user);
  }

  // 根据用户名查找用户
  async findByUsername(username: string) {
    const user = await this.usersRepository.findOne({ where: { username } });
    if (!user) throw new UnauthorizedException('用户不存在');
    return user;
  }

  // 创建用户
  async createUser(data: {
    username: string;
    password: string;
    nickname?: string;
  }) {
    const user = this.usersRepository.create(data);
    await this.usersRepository.save(user);
    return new UserVO(user);
  }
}
